/*
 * Copyright 2010 Cedric Priscal
 *
 * This file is part of stupid-avr-robot.
 *
 * stupid-avr-robot is free software: you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * stupid-avr-robot is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with stupid-avr-robot.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef ANALOGTODIGITALCONVERTER_H_
#define ANALOGTODIGITALCONVERTER_H_

#include "Timer/Timer.h"
#include "Handler.h"

#define MAX_PENDING_CONVERTIONS 8

/**
 * @brief AVR internal ADC driver.
 *
 * This class is a singleton, use @a getInstance() to retrieve it.
 */
class AnalogToDigitalConverter : public TimerListener, public Handler {

private:
	class AnalogChannel* mList[MAX_PENDING_CONVERTIONS];
	int mPutIndex;
	int mGetIndex;
	char mCount;
	void programNextADC();
	bool mRunning;
	AnalogToDigitalConverter();
	void onTimer(char what, unsigned short when);

public:

	/**
	 * @brief ADC conversion is complete.
	 * @param what Not used.
	 */
	void onEvent(char what);

	/**
	 * @brief Returns the unique instance of @a AnalogToDigitalConverter.
	 *
	 * @return A @a AnalogToDigitalConverter.
	 */
	static AnalogToDigitalConverter* getInstance();

	/**
	 * @brief Start an ADC reading on the specified channel.
	 *
	 * This method should be called only from an AnalogChannel.
	 *
	 * @param channel [in] Analog channel to read.
	 *
	 * @see AnalogChannel::startOneShot()
	 * @see AnalogChannel::startPeriodic()
	 */
	void startADC(AnalogChannel *channel);
};

#endif /* ANALOGTODIGITALCONVERTER_H_ */
